use std::env;
use dotenv::dotenv;
use sea_orm::{ Database, DatabaseConnection, PaginatorTrait, Select, Statement, DbBackend, FromQueryResult, SelectTwoMany, EntityTrait, SelectTwo };
use axum::Json;
use serde_json::{Value, json};

use serde::{ Deserialize, Serialize };
#[derive(Debug, Deserialize, Serialize, FromQueryResult)]
pub struct TableColumn {
	label:String
}
use super::{ code, query };

pub mod fun;
pub mod get_label_value;
pub mod get_auth_token;
pub mod uuid;
pub mod crud;

pub async fn send_paging_many<E,F>(selector: SelectTwo<E, F>, param:Value) -> Result<Json<Value>, Json<Value>> where E:EntityTrait, F:EntityTrait{
    let conn = connect().await?;

    let page = query::u64_op(&param, "page")?;
    let size = query::u64_op(&param, "size")?;

    let page = page.unwrap_or(1);
    let size = size.unwrap_or(10);

    let paging = selector.into_json().paginate(&conn, size);
    let result = paging.fetch_page( page-1 ).await;
    let total_nums = match paging.num_items( ).await {
        Ok(f) => f,
        Err(e) => 0
    };
    let total_pages = match paging.num_pages( ).await {
        Ok(f) => f,
        Err(e) => 0
    };
    
    match result {
        Ok(f) => {
            let data = json!({ 
                "size": size,
                "page": page,
                "total_items": total_nums,
                "total_pages": total_pages,
                "data": f
             });
             code::data(data)
        },
        Err(e) => code::sys(e.to_string())
    }
}
pub async fn send_paging_many<E,F>(selector: SelectTwoMany<E, F>, param:Value) -> Result<Json<Value>, Json<Value>> where E:EntityTrait, F:EntityTrait{
    let conn = connect().await?;

    let page = query::u64_op(&param, "page")?;
    let size = query::u64_op(&param, "size")?;

    let page = page.unwrap_or(1);
    let size = size.unwrap_or(10);

    let paging= selector.into_json().paginate(&conn, size);
    let result = paging.fetch_page( page-1 ).await;
    let total_nums = match paging.num_items( ).await {
        Ok(f) => f,
        Err(e) => 0
    };
    let total_pages = match paging.num_pages( ).await {
        Ok(f) => f,
        Err(e) => 0
    };
    
    match result {
        Ok(f) => {
            let data = json!({ 
                "size": size,
                "page": page,
                "total_items": total_nums,
                "total_pages": total_pages,
                "data": f
             });
             code::data(data)
        },
        Err(e) => code::sys(e.to_string())
    }
}